package com.boyon.customer.service.customer.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.type.LongType;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.boyon.common.domain.UserSession;
import com.boyon.common.exection.BusinessException;
import com.boyon.common.session.SessionManager;
import com.boyon.common.status.RateType;
import com.boyon.common.status.RelationType;
import com.boyon.common.status.ReportType;
import com.boyon.common.tools.CollectionTool;
import com.boyon.common.tools.ObjectTool;
import com.boyon.common.tools.StringTool;
import com.boyon.customer.domain.AgentReportRateData;
import com.boyon.customer.entity.AgentReportRate;
import com.boyon.customer.entity.Customer;
import com.boyon.hbm.criteria.OperationType;
import com.boyon.hbm.criteria.Param;
import com.boyon.hbm.criteria.Query;
import com.boyon.service.AbstractService;

/**
 * ClassName:AgentReportRateService <br/>
 * Function: 代理商费用比例设置. <br/>
 * Date: 2018年4月8日 下午9:16:38 <br/>
 * 
 * @author sunshulin
 * @version
 * @since JDK 1.8
 * @see
 */
@Service
public class AgentReportRateService extends AbstractService {

	/**
	 * 
	 * editor:编辑代理商报告收费比例. <br/>
	 * 
	 * @author sunshulin
	 * @param data
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional
	public Long editor(AgentReportRateData data) {
		ReportType reportType = ReportType.getType(data.getReportType());
		List<AgentReportRate> list = search(data.getCustomerId(), reportType);
		if (!ObjectTool.isNotNull(data.getAgentReportRateId())
				&& CollectionTool.isNotEmpty(list)) {
			throw BusinessException.builder(0, "代理商已设置比例");
		}
		AgentReportRate agentReportRate = new AgentReportRate();
		agentReportRate.setAgentReportRateId(data.getAgentReportRateId());
		agentReportRate.setCustomerId(data.getCustomerId());
		agentReportRate.setRateType(data.getRateType());
		agentReportRate.setRate(BigDecimal.ZERO);
		agentReportRate.setFreeNum(0);
		agentReportRate.setNum(0);
		agentReportRate.setPrice(BigDecimal.ZERO);
		agentReportRate.setReportType(data.getReportType());
		if (reportType == ReportType.charge) {
			RateType rateType = RateType.getType(data.getRateType());
			if (rateType == RateType.divide) {
				// 分成比例保存比例值
				agentReportRate.setRate(data.getRate());
			} else if (rateType == RateType.fixed) {
				// 固定金额
				agentReportRate.setPrice(data.getPrice());
			}
		} else if (reportType == ReportType.free) {
			// 按数量收取
			agentReportRate.setFreeNum(data.getFreeNum());
			agentReportRate.setNum(data.getNum());
			agentReportRate.setPrice(data.getPrice());
		}
		generalDao.saveOrUpdate(agentReportRate);
		UserSession userSession = SessionManager.getUserSession();
		if (userSession.getRelationType().equals(RelationType.agent.getVal())) {
			agentReportRate.setQueryPath(userSession.getQueryPath());
		} else if (userSession.getRelationType()
				.equals(RelationType.system.getVal())) {
			agentReportRate.setQueryPath("0");
		}
		return agentReportRate.getCustomerId();
	}

	/**
	 * 
	 * find:查找代理商比例设置信息. <br/>
	 * 
	 * @author sunshulin
	 * @param customerId
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional
	public AgentReportRateData find(Long agentReportRateId) {
		AgentReportRate agentReportRate = get(agentReportRateId);
		AgentReportRateData agentReportRateData = new AgentReportRateData();
		ObjectTool.copy(agentReportRate, agentReportRateData);
		Customer customer = generalDao.get(Customer.class, agentReportRateId);
		if (ObjectTool.isNotNull(customer)) {
			agentReportRateData.setCustomerName(customer.getCustomerName());
		}
		return agentReportRateData;
	}

	/**
	 * 
	 * delete:删除代理商设置比例. <br/>
	 * 
	 * @author sunshulin
	 * @param customerId
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional
	public Long delete(Long customerId) {
		generalDao.delete(AgentReportRate.class, customerId);
		return customerId;
	}

	/**
	 * 
	 * find:代理商id查询. <br/>
	 * 
	 * @author sunshulin
	 * @param customerId
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional
	public AgentReportRate get(Long agentReportRateId) {
		return generalDao.get(AgentReportRate.class, agentReportRateId);
	}

	/**
	 * 
	 * query:查询代理商分成列表. <br/>
	 * 
	 * @author sunshulin
	 * @param data
	 * @param query
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional
	public List<AgentReportRateData> query(AgentReportRateData data,
			Query query) {
		List<AgentReportRateData> list = new ArrayList<>();
		if (StringTool.isNotNull(data.getCustomerName())) {
			query.addParam(new Param<Object[]>(
					"(select from base_customer where this_.customer_id=base_customer.customer_id and base_customer.customer_name like ?)",
					OperationType.sql,
					new Object[] { data.getCustomerName() + "%" },
					new Type[] { StringType.INSTANCE }));
		}
		query.addParam(new Param<Integer>("reportType", OperationType.eq,
				data.getReportType()));
		query.addParam(new Param<Integer>("rateType", OperationType.eq,
				data.getRateType()));
		UserSession userSession = SessionManager.getUserSession();
		if (userSession.getRelationType().equals(RelationType.agent.getVal())) {
			query.addParam(new Param<Object[]>(
					"this_.customer_id in (select a.customer_id from boyon_customer.base_agent_relation a where parent_customer_id= ?)",
					OperationType.sql, new Object[] {userSession.getRelationId()}, new Type[] {LongType.INSTANCE}));
			query.addParam(new Param<Long>("customerId", OperationType.nq,
					userSession.getRelationId()));
		} else if (userSession.getRelationType()
				.equals(RelationType.system.getVal())) {
			query.addParam(
					new Param<String>("queryPath", OperationType.eq, "0"));
		}
		List<AgentReportRate> agentReportRates = generalDao
				.query(AgentReportRate.class, query);
		for (AgentReportRate agentReportRate : agentReportRates) {
			AgentReportRateData agentReportRateData = new AgentReportRateData();
			ObjectTool.copy(agentReportRate, agentReportRateData);
			Customer customer = generalDao.get(Customer.class,
					agentReportRate.getCustomerId());
			if (ObjectTool.isNotNull(customer)) {
				agentReportRateData.setCustomerName(customer.getCustomerName());
			}
			list.add(agentReportRateData);
		}
		return list;
	}

	/**
	 * 
	 * search:查询客户报告结算设置. <br/>
	 * 
	 * @author sunshulin
	 * @param query
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional
	public List<AgentReportRate> search(Long customerId,
			ReportType reportType) {
		Query query = new Query();
		query.addParam(
				new Param<Long>("customerId", OperationType.eq, customerId));
		query.addParam(new Param<Integer>("reportType", OperationType.eq,
				reportType.getVal()));
		return generalDao.query(AgentReportRate.class, query);
	}
}
